﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Runtime.Serialization;
using System.Reflection;

namespace MyLibrary.Text.JSON.Utility
{
    public class UtilityClass
    {
        public interface ISetUtility : ICollection, IList
        {
            new bool Add(Object obj);
            bool AddAll(ICollection collection);
        }

        public interface ISortedSetUtility : ISetUtility
        {
            ISortedSetUtility HeadSet(Object limit);
            ISortedSetUtility SubSet(Object lowerLimit, Object upperLimit);
            ISortedSetUtility TailSet(Object limit);
        }

        public static void WriteStackTrace(Exception throwable, TextWriter stream)
        {
            stream.Write(throwable.StackTrace);
            stream.Flush();
        }

        public static void DefaultReadObject(SerializationInfo info, StreamingContext context, Object instance)
        {
            Type thisType = instance.GetType();
            MemberInfo[] mi = FormatterServices.GetSerializableMembers(thisType, context);
            for (int i = 0; i < mi.Length; i++)
            {
                FieldInfo fi = (FieldInfo)mi[i];
                fi.SetValue(instance, info.GetValue(fi.Name, fi.FieldType));
            }
        }

        public static void DefaultWriteObject(SerializationInfo info, StreamingContext context, Object instance)
        {
            Type thisType = instance.GetType();
            MemberInfo[] mi = FormatterServices.GetSerializableMembers(thisType, context);
            for (int i = 0; i < mi.Length; i++)
                info.AddValue(mi[i].Name, ((FieldInfo)mi[i]).GetValue(instance));
        }

        [Serializable]
        public class HashSetUtility : ArrayList, ISetUtility
        {
            #region 构造函数
            public HashSetUtility()
                : base()
            {

            }
            public HashSetUtility(ICollection collection)
            {
                this.AddAll(collection);
            }
            public HashSetUtility(int capactity)
                : base(capactity)
            {
            }
            #endregion

            public new virtual bool Add(object obj)
            {
                bool inserted = false;
                if ((inserted = this.Contains(obj)) == false)
                    base.Add(obj);
                return !inserted;
            }

            public bool AddAll(ICollection collection)
            {
                IEnumerator e = new ArrayList(collection).GetEnumerator();
                bool added = false;

                while (e.MoveNext())
                {
                    if (this.Add(e.Current) == true)
                        added = true;
                }
                return added;
            }

            public override object Clone()
            {
                return base.MemberwiseClone();
            }
        }

        [Serializable]
        public class TreeSetUtility : ArrayList, ISetUtility, ISortedSetUtility
        {
            private IComparer comparator = Comparer.Default;

            public IComparer Comparator
            {
                get { return comparator; }
            }

            #region 构造函数
            public TreeSetUtility()
                : base()
            {
            }
            public TreeSetUtility(ICollection collection)
                : base()
            {
                
            }

            public TreeSetUtility(IComparer comparer)
                : base()
            {
                this.comparator = comparator;
            }
            #endregion

            #region ISetUtility Members

            public new bool Add(object obj)
            {
                bool inserted = false;
                if (!(inserted = this.Contains(obj)))
                {
                    base.Add(obj);
                    base.Sort(this.comparator);
                }
            }

            public bool AddAll(ICollection collection)
            {
                IEnumerator e = new ArrayList(collection).GetEnumerator();
                bool added = false;
                while (e.MoveNext())
                {
                    if (this.Add(e.Current))
                        added = true;
                }
                this.Sort(this.comparator);
                return added;
            }

            #endregion

            #region ISortedSetUtility Members
            public ISortedSetUtility HeadSet(Object limit)
            {
                ISortedSetUtility newList = new TreeSetUtility();
                for (int i = 0; i < this.Count; i++)
                {
                    if (this.comparator.Compare(this[i], limit) >= 0)
                        break;
                    newList.Add(this[i]);
                }
                return newList;
            }

            public ISortedSetUtility SubSet(Object lowerLimit, Object upperLimit)
            {
                ISortedSetUtility newList = new TreeSetUtility();
                int i = 0;
                while (this.comparator.Compare(this[i], lowerLimit) < 0)
                    i++;
                for (; i < this.Count; i++)
                {
                    if (this.comparator.Compare(this[i], upperLimit) >= 0)
                        break;
                    newList.Add(this[i]);
                }
            }

            public ISortedSetUtility TailSet(Object limit)
            {
                ISortedSetUtility newList = new TreeSetUtility();
                int i = 0;

                while (this.comparator.Compare(this[i], limit) < 0)
                    i++;
                for (; i < this.Count; i++)
                    newList.Add(this[i]);
                return newList;
            }
            #endregion

            public override bool Contains(object item)
            {
                IEnumerator tempEnumerator = this.GetEnumerator();
                while (tempEnumerator.MoveNext())
                    if (this.comparator.Compare(tempEnumerator.Current, item) == 0)
                        return true;
                return false;
            }
        }

        public class ICollectionSupport
        {
            public static bool Add(ICollection collection, Object obj)
            {
                bool added = false;
                MethodInfo method;
                try
                {
                    method = collection.GetType().GetMethod("Add");
                    if (method == null)
                        method = collection.GetType().GetMethod("add");
                    int index = (int)method.Invoke(collection, new Object[] { obj });
                    if (index >= 0)
                        added = true;
                }
                catch (Exception ex)
                {
                    throw ex;
                }
            }

            public static bool AddAll(ICollection target, ICollection collection)
            {
                IEnumerator e = new ArrayList(collection).GetEnumerator();
                bool added = false;

                MethodInfo method;
                try
                {
                    method = target.GetType().GetMethod("addAll");
                    if (method != null)
                        added = (bool)method.Invoke(target, new Object[] { collection });
                    else
                    {
                        method = target.GetType().GetMethod("Add");
                        while (e.MoveNext())
                        {
                            bool tempAdded = (int)method.Invoke(target, new Object[] { e.Current }) >= 0;
                            added = added ? added : tempAdded;
                        }
                    }
                }
                catch (Exception ex)
                {
                    throw ex;
                }
            }
        }
    }
}
